﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;

namespace RunningWavelet.WpfPlots
{
    /// <summary>
    ///     Interaction logic for PlotView.xaml
    /// </summary>
    public partial class PlotView
    {
        private readonly ConcurrentDictionary<int, List<DataPoint>> seriesData = new ConcurrentDictionary<int, List<DataPoint>>();

        private readonly ConcurrentDictionary<int, LineSeries> seriesDic = new ConcurrentDictionary<int, LineSeries>();
        public string LegendCaption { get; set; }
        public PlotModel PlotModel { get; private set; }
        public int PlotCapacity { get; set; }


        public PlotView()
        {
            InitializeComponent();
            DataContext = this;

            PlotModel = new PlotModel();
            SetUpModel();
            //var lineSerie = GetOrCreateSeries(1, LegendCaption);
            //InitPlotData(lineSerie);
        }


        
        public void InitPlotData(LineSeries ls)
        {
            /* Тестирование графика
             * var po = new List<DataPoint>
            {
                new DataPoint(0, 4),
                new DataPoint(10, 13),
                new DataPoint(20, 15),
                new DataPoint(30, 16),
                new DataPoint(40, 12),
                new DataPoint(50, 12)
            };
            seriesData.TryAdd(1, po);
            ls.ItemsSource = seriesData[1];*/

            seriesData.TryAdd(1, new List<DataPoint>());
            GetRandomData()
                .ToList()
                .ForEach(d => seriesData[1].Add(new DataPoint(DateTimeAxis.ToDouble(d.DateTime), d.Value)));
            ls.ItemsSource = seriesData[1];
        }

        public void UpdateSerie(int serieNumber, IEnumerable<DataPoint> serieValues)
        {
            GetOrCreateSeries(serieNumber).ItemsSource = serieValues;
        }

        public void PlotRefresh()
        {
            PlotModel.InvalidatePlot(true);
            PlotModel.ResetAllAxes();
        }

        private void SetUpModel()
        {
            PlotModel.LegendOrientation = LegendOrientation.Vertical;
            PlotModel.LegendPlacement = LegendPlacement.Inside;
            PlotModel.LegendPosition = LegendPosition.TopRight;
            PlotModel.LegendBackground = OxyColor.FromAColor(200, OxyColors.White);
            PlotModel.LegendBorder = OxyColors.Black;

            var dateAxis = new DateTimeAxis
            {
                StringFormat = "mm:ss",
                MajorGridlineStyle = LineStyle.Solid,
                MinorGridlineStyle = LineStyle.Dot,
                IntervalLength = 80
            };
            PlotModel.Axes.Add(dateAxis);

            var valueAxis = new LinearAxis
            {
                MajorGridlineStyle = LineStyle.Solid,
                MinorGridlineStyle = LineStyle.Dot
            };
            PlotModel.Axes.Add(valueAxis);
        }

        public LineSeries GetOrCreateSeries(int parameterId, string legend = null)
        {
            return seriesDic.GetOrAdd(parameterId, key =>
            {
                var lineSeries = new LineSeries
                {
                    StrokeThickness = 2,
                    MarkerSize = 3,
                    //MarkerStroke = colors[data.Key],                  //форматирование графиков цветом
                    //MarkerType = markerTypes[data.Key],               //маркеры данных на графике
                    CanTrackerInterpolatePoints = false,
                    Title = legend ?? string.Format("Канал # {0}", parameterId), //легенда
                    Smooth = false
                };

                PlotModel.Series.Add(lineSeries);
                return lineSeries;
            });
        }
        
        public static List<Measurement> GetRandomData()
        {
            var measurements = new List<Measurement>();
            var startDate = DateTime.Now.AddMinutes(-10);
            var r = new Random();

            for (var j = 0; j < 11; j++)
            {
                measurements.Add(new Measurement
                {
                    DetectorId = 1,
                    DateTime = startDate.AddMinutes(j),
                    Value = r.Next(1, 30)
                });
            }

            measurements.Sort((m1, m2) => m1.DateTime.CompareTo(m2.DateTime));
            return measurements;
        }

        public static List<Measurement> GetUpdateData(DateTime dateTime)
        {
            var measurements = new List<Measurement>();
            var r = new Random();

            for (var i = 0; i < 5; i++)
            {
                measurements.Add(new Measurement
                {
                    DetectorId = i,
                    DateTime = dateTime.AddSeconds(1),
                    Value = r.Next(1, 30)
                });
            }
            return measurements;
        }
    }

    public class Measurement
    {
        public int DetectorId { get; set; }
        public int Value { get; set; }
        public DateTime DateTime { get; set; }
    }
}